﻿using System;
using System.Linq;

using Microsoft.Web.XmlTransform;

using MiP.Common;

namespace MiP.Xml.Core
{
    public class TransformationLogger : IXmlTransformationLogger
    {
        #region Private Fields

        private readonly ILogger _logger;

        #endregion

        #region Initialization

        public TransformationLogger(ILogger logger)
        {
            if (logger == null)
                throw new ArgumentNullException("logger");

            _logger = logger;
        }

        #endregion

        #region Private Methods

        private void LogOrThrowError(string formatString, params object[] args)
        {
            if (args.OfType<string>().Any(text => text != null && text.Contains("No element in the source document matches")))
                _logger.Warn(formatString, args);
            else
                throw new InvalidOperationException(string.Format(formatString, args));
        }

        #endregion

        #region Interface Implementation: IXmlTransformationLogger

        public void LogMessage(string message, params object[] messageArgs)
        {
            _logger.Info(message, messageArgs);
        }

        public void LogMessage(MessageType type, string message, params object[] messageArgs)
        {
            _logger.Info(message, messageArgs);
        }

        public void LogWarning(string message, params object[] messageArgs)
        {
            _logger.Warn(message, messageArgs);
        }

        public void LogWarning(string file, string message, params object[] messageArgs)
        {
            _logger.Warn(string.Format("File: {0}, Message: {1}", file, message), messageArgs);
        }

        public void LogWarning(string file, int lineNumber, int linePosition, string message, params object[] messageArgs)
        {
            _logger.Warn(string.Format("File: {0}, Line: {1}, Column: {2}, Message: {3}", file, lineNumber, linePosition, message), messageArgs);
        }

        // errors reported by this logger are more like a warning for the user.
        public void LogError(string message, params object[] messageArgs)
        {
            LogOrThrowError(message, messageArgs);
        }

        public void LogError(string file, string message, params object[] messageArgs)
        {
            LogOrThrowError(string.Format("File: {0}, Message: {1}", file, message), messageArgs);
        }

        public void LogError(string file, int lineNumber, int linePosition, string message, params object[] messageArgs)
        {
            LogOrThrowError(string.Format("File: {0}, Line: {1}, Column: {2}, Message: {3}", file, lineNumber, linePosition, message), messageArgs);
        }

        public void LogErrorFromException(Exception ex)
        {
            LogOrThrowError("Exception: {0}", ex.Message);
        }

        public void LogErrorFromException(Exception ex, string file)
        {
            LogOrThrowError("File: {0}, Exception: {1}", file, ex.Message);
        }

        public void LogErrorFromException(Exception ex, string file, int lineNumber, int linePosition)
        {
            LogOrThrowError("File: {0}, Line: {1}, Column: {2}, Exception: {3}", file, lineNumber, linePosition, ex.Message);
        }

        public void StartSection(string message, params object[] messageArgs)
        {
            _logger.Info(string.Format("StartSection {0}", message), messageArgs);
        }

        public void StartSection(MessageType type, string message, params object[] messageArgs)
        {
            _logger.Info(string.Format("StartSection {0}", message), messageArgs);
        }

        public void EndSection(string message, params object[] messageArgs)
        {
            _logger.Info(string.Format("EndSection {0}", message), messageArgs);
        }

        public void EndSection(MessageType type, string message, params object[] messageArgs)
        {
            _logger.Info(string.Format("EndSection {0}", message), messageArgs);
        }

        #endregion
    }
}